home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / ncurses-5.3 / ncurses / base / wresize.c < prev   
Encoding:
C/C++ Source or Header  |  2002-10-27  |  7.5 KB  |  240 lines

  1. /****************************************************************************
  2.  * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
  3.  *                                                                          *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  5.  * copy of this software and associated documentation files (the            *
  6.  * "Software"), to deal in the Software without restriction, including      *
  7.  * without limitation the rights to use, copy, modify, merge, publish,      *
  8.  * distribute, distribute with modifications, sublicense, and/or sell       *
  9.  * copies of the Software, and to permit persons to whom the Software is    *
  10.  * furnished to do so, subject to the following conditions:                 *
  11.  *                                                                          *
  12.  * The above copyright notice and this permission notice shall be included  *
  13.  * in all copies or substantial portions of the Software.                   *
  14.  *                                                                          *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  16.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  18.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  21.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  22.  *                                                                          *
  23.  * Except as contained in this notice, the name(s) of the above copyright   *
  24.  * holders shall not be used in advertising or otherwise to promote the     *
  25.  * sale, use or other dealings in this Software without prior written       *
  26.  * authorization.                                                           *
  27.  ****************************************************************************/
  28.  
  29. /****************************************************************************
  30.  *  Author: Thomas E. Dickey 1996-2002                                      *
  31.  ****************************************************************************/
  32.  
  33. #include <curses.priv.h>
  34.  
  35. MODULE_ID("$Id: wresize.c,v 1.23 2002/09/28 15:15:51 tom Exp $")
  36.  
  37. static int
  38. cleanup_lines(struct ldat *data, int length)
  39. {
  40.     while (--length >= 0)
  41.     free(data->text);
  42.     free(data);
  43.     return ERR;
  44. }
  45.  
  46. /*
  47.  * If we have reallocated the ldat structs, we will have to repair pointers
  48.  * used in subwindows.
  49.  */
  50. static void
  51. repair_subwindows(WINDOW *cmp)
  52. {
  53.     WINDOWLIST *wp;
  54.     struct ldat *pline = cmp->_line;
  55.     int row;
  56.  
  57.     for (wp = _nc_windows; wp != 0; wp = wp->next) {
  58.     WINDOW *tst = &(wp->win);
  59.  
  60.     if (tst->_parent == cmp) {
  61.  
  62.         if (tst->_pary > cmp->_maxy)
  63.         tst->_pary = cmp->_maxy;
  64.         if (tst->_parx > cmp->_maxx)
  65.         tst->_parx = cmp->_maxx;
  66.  
  67.         if (tst->_maxy + tst->_pary > cmp->_maxy)
  68.         tst->_maxy = cmp->_maxy - tst->_pary;
  69.         if (tst->_maxx + tst->_parx > cmp->_maxx)
  70.         tst->_maxx = cmp->_maxx - tst->_parx;
  71.  
  72.         for (row = 0; row <= tst->_maxy; ++row) {
  73.         tst->_line[row].text = &pline[tst->_pary + row].text[tst->_parx];
  74.         }
  75.         repair_subwindows(tst);
  76.     }
  77.     }
  78. }
  79.  
  80. /*
  81.  * Reallocate a curses WINDOW struct to either shrink or grow to the specified
  82.  * new lines/columns.  If it grows, the new character cells are filled with
  83.  * blanks.  The application is responsible for repainting the blank area.
  84.  */
  85. NCURSES_EXPORT(int)
  86. wresize(WINDOW *win, int ToLines, int ToCols)
  87. {
  88.     int col, row, size_x, size_y;
  89.     struct ldat *pline;
  90.     struct ldat *new_lines = 0;
  91.  
  92. #ifdef TRACE
  93.     T((T_CALLED("wresize(%p,%d,%d)"), win, ToLines, ToCols));
  94.     if (win) {
  95.     TR(TRACE_UPDATE, ("...beg (%d, %d), max(%d,%d), reg(%d,%d)",
  96.               win->_begy, win->_begx,
  97.               win->_maxy, win->_maxx,
  98.               win->_regtop, win->_regbottom));
  99.     if (_nc_tracing & TRACE_UPDATE)
  100.         _tracedump("...before", win);
  101.     }
  102. #endif
  103.  
  104.     if (!win || --ToLines < 0 || --ToCols < 0)
  105.     returnCode(ERR);
  106.  
  107.     size_x = win->_maxx;
  108.     size_y = win->_maxy;
  109.  
  110.     if (ToLines == size_y
  111.     && ToCols == size_x)
  112.     returnCode(OK);
  113.  
  114.     if ((win->_flags & _SUBWIN)) {
  115.     /*
  116.      * Check if the new limits will fit into the parent window's size.  If
  117.      * not, do not resize.  We could adjust the location of the subwindow,
  118.      * but the application may not like that.
  119.      */
  120.     if (win->_pary + ToLines > win->_parent->_maxy
  121.         || win->_parx + ToCols > win->_parent->_maxx) {
  122.         returnCode(ERR);
  123.     }
  124.     pline = win->_parent->_line;
  125.     } else {
  126.     pline = 0;
  127.     }
  128.  
  129.     /*
  130.      * Allocate new memory as needed.  Do the allocations without modifying
  131.      * the original window, in case an allocation fails.  Always allocate
  132.      * (at least temporarily) the array pointing to the individual lines.
  133.      */
  134.     new_lines = typeCalloc(struct ldat, (unsigned) (ToLines + 1));
  135.     if (new_lines == 0)
  136.     returnCode(ERR);
  137.  
  138.     /*
  139.      * For each line in the target, allocate or adjust pointers for the
  140.      * corresponding text, depending on whether this is a window or a
  141.      * subwindow.
  142.      */
  143.     for (row = 0; row <= ToLines; ++row) {
  144.     int begin = (row > size_y) ? 0 : (size_x + 1);
  145.     int end = ToCols;
  146.     NCURSES_CH_T *s;
  147.  
  148.     if (!(win->_flags & _SUBWIN)) {
  149.         if (row <= size_y) {
  150.         if (ToCols != size_x) {
  151.             if ((s = typeMalloc(NCURSES_CH_T, ToCols + 1)) == 0)
  152.             returnCode(cleanup_lines(new_lines, row));
  153.             for (col = 0; col <= ToCols; ++col) {
  154.             s[col] = (col <= size_x
  155.                   ? win->_line[row].text[col]
  156.                   : win->_nc_bkgd);
  157.             }
  158.         } else {
  159.             s = win->_line[row].text;
  160.         }
  161.         } else {
  162.         if ((s = typeMalloc(NCURSES_CH_T, ToCols + 1)) == 0)
  163.             returnCode(cleanup_lines(new_lines, row));
  164.         for (col = 0; col <= ToCols; ++col)
  165.             s[col] = win->_nc_bkgd;
  166.         }
  167.     } else {
  168.         s = &pline[win->_pary + row].text[win->_parx];
  169.     }
  170.  
  171.     if_USE_SCROLL_HINTS(new_lines[row].oldindex = row);
  172.     if (row <= size_y) {
  173.         new_lines[row].firstchar = win->_line[row].firstchar;
  174.         new_lines[row].lastchar = win->_line[row].lastchar;
  175.     }
  176.     if ((ToCols != size_x) || (row > size_y)) {
  177.         if (end >= begin) {    /* growing */
  178.         if (new_lines[row].firstchar < begin)
  179.             new_lines[row].firstchar = begin;
  180.         } else {        /* shrinking */
  181.         new_lines[row].firstchar = 0;
  182.         }
  183.         new_lines[row].lastchar = ToCols;
  184.     }
  185.     new_lines[row].text = s;
  186.     }
  187.  
  188.     /*
  189.      * Dispose of unwanted memory.
  190.      */
  191.     if (!(win->_flags & _SUBWIN)) {
  192.     if (ToCols == size_x) {
  193.         for (row = ToLines + 1; row <= size_y; row++) {
  194.         free(win->_line[row].text);
  195.         }
  196.     } else {
  197.         for (row = 0; row <= size_y; row++) {
  198.         free(win->_line[row].text);
  199.         }
  200.     }
  201.     }
  202.  
  203.     free(win->_line);
  204.     win->_line = new_lines;
  205.  
  206.     /*
  207.      * Finally, adjust the parameters showing screen size and cursor
  208.      * position:
  209.      */
  210.     win->_maxx = ToCols;
  211.     win->_maxy = ToLines;
  212.  
  213.     if (win->_regtop > win->_maxy)
  214.     win->_regtop = win->_maxy;
  215.     if (win->_regbottom > win->_maxy
  216.     || win->_regbottom == size_y)
  217.     win->_regbottom = win->_maxy;
  218.  
  219.     if (win->_curx > win->_maxx)
  220.     win->_curx = win->_maxx;
  221.     if (win->_cury > win->_maxy)
  222.     win->_cury = win->_maxy;
  223.  
  224.     /*
  225.      * Check for subwindows of this one, and readjust pointers to our text,
  226.      * if needed.
  227.      */
  228.     repair_subwindows(win);
  229.  
  230. #ifdef TRACE
  231.     TR(TRACE_UPDATE, ("...beg (%d, %d), max(%d,%d), reg(%d,%d)",
  232.               win->_begy, win->_begx,
  233.               win->_maxy, win->_maxx,
  234.               win->_regtop, win->_regbottom));
  235.     if (_nc_tracing & TRACE_UPDATE)
  236.     _tracedump("...after:", win);
  237. #endif
  238.     returnCode(OK);
  239. }
  240.